import { _decorator, Asset, assetManager, AssetManager, Component, error, Node } from 'cc';
import Singleton from '../Common/Singleton';
const { ccclass, property } = _decorator;

@ccclass('ResMgr')
export class ResMgr extends Singleton<ResMgr>() {
    private _mapBundle: Map<string, AssetManager.Bundle> = new Map();

    async loadBundle(name: string): Promise<AssetManager.Bundle> {
        return new Promise((resolve, reject) => {
            let path = name;
            assetManager.loadBundle(path, (err: Error, bundle: AssetManager.Bundle) => {
                if (err) {
                    return;
                }
                this._mapBundle.set(name, bundle);
                resolve(bundle);
            })
        })
    }

    async loadRes<T extends Asset>(bundleName: string, path: string): Promise<T> {
        let bundle = this.getBundle(bundleName);
        if (!bundle) {
            await this.loadBundle(bundleName).then((ret: AssetManager.Bundle) => {
                bundle = ret;
            });
            if (!bundle) {
                error('加载' + path + '资源时去加载' + bundleName + '出错');
                return null;
            }
        }
        return new Promise((resolve, reject) => {
            bundle.load(path, (err, ret) => {
                if (err) {
                    return;
                }
                resolve(ret as T);
            });
        })
    }

    getBundle(name: string): AssetManager.Bundle {
        return this._mapBundle.get(name);
    }

    //已经有加载过的资源会被存储到包里，直接获取到对应ab包，get出来。
    getRes<T extends Asset>(bundleName: string, resName: string): T {
        if (!bundleName || bundleName.length <= 0 || !resName || resName.length <= 0) {
            return null;
        }
        let bundle = this.getBundle(bundleName);
        if (!bundle) {
            return null;
        }

        return bundle.get(resName);
    }

    //临时按需。
    async getResWithNeed<T extends Asset>(bundleName: string, resName: string): Promise<T> {
        if (!bundleName || bundleName.length <= 0 || !resName || resName.length <= 0) {
            return null;
        }
        let bundle = this.getBundle(bundleName);
        if (!bundle) {
            return null;
        }

        return new Promise((resolve, reject) => {
            bundle.load(resName, (err, asset) => {
                if (err) {
                    return;
                }
                resolve(asset as T);
            });
        });
    }
}